using IcsSEMCtrl.Db;
using IcsSEMCtrl.Device.Observe;
using IcsSEMCtrl.Global.Device;
using IcsSEMCtrl.Service.Logger;
using IcsSEMCtrl.Service.Material;
using IcsSEMCtrl.Util.Client;
using Lifter.Device.Dispatcher;
using Lifter.Event.Lifter;
using Lifter.Global;
using Lifter.Global.Device;
using Lifter.Gui.Monitor.Panels;
using Lifter.Gui.Monitor.Popups;
using Lifter.Utility;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading;
using TKT.Lifter.CIM.Lifter.Event.Lifter;
using TKT.Lifter.CIM.Lifter.Gui.Monitor.Panels;
using static TKT.Lifter.CIM.Lifter.Global.SysTemConstant;

namespace Lifter.Device.Unit
{
    public class LifterPort : LocationUnit
    {
        private enum enumCIMPortSetResetCase
        {
            FAULT_RESET,
            RUN_REQ,
            DOWN_REQ,
            INPUT_MODE_REQ,
            OUTPUT_MODE_REQ,
            BI_MODE_REQ,
            INPUT_PORT_BCR_SET,
            INPUT_RF_READ_DONE_ACK,
            OUPUT_RF_READ_DONE_ACK
        }
        private enum enumHandOfftype
        {
            MANUAL = 1,
            AUTO
        }
        private const string CLASS = "LifterPort";
        public const string INSIDE_BUFFER = "1";
        private LifterSEM lftSem;
        private HandOffType portHandoffType = HandOffType.AGV;
        private ElevType portElevType = ElevType.NORMAL;
        private int portSize = 0;
        private bool isCombine = false;//是否在过度CV上报waitIn,生成指令
        private bool isNextLocation = false;
        private Dictionary<string, NextLocation> nextLocationInfo = null;
        private PortType lifterPortType = PortType.LP;
        public enumLifterPortDirection portInOutMode = enumLifterPortDirection.OUT; //Port口方向
        private enumLifterPortOperationModeForAIM operationModeForAIM = enumLifterPortOperationModeForAIM.AUTO;
        private enumHandOfftype enumHandOfftypeForAIM = enumHandOfftype.AUTO;
        private enumAIMLifertPortInOutType portAIMInOutType = enumAIMLifertPortInOutType.UNKNOWN;
        private bool isPortBiDir = true;
        private enumRIDState lifterPortState = enumRIDState.DOWN;
        private enumPortStateForAim portStateForAim = enumPortStateForAim.OutofService;
        private enumIDReadState inputBCRReadStatus = enumIDReadState.SUCCESS;
        private PortWIWO waitIn = PortWIWO.NONE;
        private PortWIWO waitOut = PortWIWO.NONE;
        private string carrierId = "";
        private string OutputCarrierID = "";//针对出料口扫码不匹配的ID
        private bool[] carrierPresence = new bool[21];
        private CarrierElevType carrierElevType = CarrierElevType.NORMAL;
        private bool isOutputEnable = false;//Port能排出cst
        private bool isPortDirChangeEnable = false;
        private bool isOutPutRequestOK = true;
        private bool isOutPutRequestNG = false;
        private bool isOutPutRequest = false;
        private enumPortTransferState portTrasferState = enumPortTransferState.NONE;
        private DateTime waitInTime = DateTime.MinValue;
        private bool isUSECVWaitTimeOut = false;
        private bool isUSEOfflineAutoCMD = false;
        private string portPrity = "";//port口
        private string offlineAutoCMD_DestPort = "";
        private bool useDestPortFlag = false;
        private bool portUse = false;//port口enable
        private string rptAlarmID = "";
        private string rptAlarmText = "";
        public bool isIUsernputCSTIDReserved = false;
        public string strReservedCSTID = "";
        public string prevDestPort = "";
        private bool isBIDIRECTIONMODEREQ = false;
        private bool isDownReqeust = false;
        private bool isFAULTRESET = false;
        private bool isINPUTMODEREQ = false;
        private bool isINPUTPORTBCRSET = false;
        private bool isOUTPUTMODEREQ = false;
        private bool isRunReqeust = false;
        private int floor = 0; //port口所属楼层
        public enumBCREnableMode bcrEnableMode = enumBCREnableMode.ENABLE;//BCR禁用使用模式(ENABLE/DISABLE)
        private bool isHostCommandTimeOut = false;//是否已经Host超时，PC自动生成指令了
        Dictionary<string, int> PortPIODict = new Dictionary<string, int>();
        public delegate void PIODelegate(int value);
        public PIODelegate pIODelegate;
        public delegate void SenserInfoDelegate(int value);
        public SenserInfoDelegate senserInfoDelegate;
        private enumHandOfftype enumPortManualMode = enumHandOfftype.AUTO;//PORT口取料是否是自动模式或手动模式
        public LifterSEM LftSem
        {
            get
            {
                if (this.lftSem == null)
                {
                    this.lftSem = (LifterSEM)Naming.GetDeviceManager().GetDevice();
                }
                return this.lftSem;
            }
        }
        public HandOffType PortHandoffType
        {
            get
            {
                return this.portHandoffType;
            }
            set
            {
                this.portHandoffType = value;
                if (portHandoffType == HandOffType.MGV)
                {
                    //改变Port操作模式为手动
                    this.OperationModeForAIM = enumLifterPortOperationModeForAIM.MANUAL;
                    this.enumHandOfftypeForAIM = enumHandOfftype.MANUAL;
                }
                else
                {
                    //改变Port操作模式为自动
                    this.OperationModeForAIM = enumLifterPortOperationModeForAIM.AUTO;
                    this.enumHandOfftypeForAIM = enumHandOfftype.AUTO;
                }
            }
        }
        public ElevType PortElevType
        {
            get
            {
                return this.portElevType;
            }
            set
            {
                this.portElevType = value;
            }
        }
        public int PortSize
        {
            get
            {
                return this.portSize;
            }
            set
            {
                this.portSize = value;
            }
        }
        public Dictionary<string, NextLocation> NextLocationInfo
        {
            get
            {
                return this.nextLocationInfo;
            }
            set
            {
                this.nextLocationInfo = value;
            }
        }
        public enumLifterPortDirection PortInOutMode
        {
            get
            {
                return this.portInOutMode;
            }
            set
            {
                this.portInOutMode = value;
            }
        }
        public enumAIMLifertPortInOutType PortAIMInOutType
        {
            get
            {
                return this.portAIMInOutType;
            }
            set
            {
                if (value != this.portAIMInOutType)
                {
                    this.portAIMInOutType = value;
                    this.LftSem.SecsDriver.SendMessage("S6F11", "405", this);
                }
            }
        }
        public bool IsPortBiDir
        {
            get
            {
                return this.isPortBiDir;
            }
            set
            {
                this.isPortBiDir = value;
            }
        }
        public enumRIDState LifterPortState
        {
            get
            {
                return this.lifterPortState;
            }
            set
            {
                this.lifterPortState = value;
            }
        }
        public enumIDReadState InputBCRReadStatus
        {
            get
            {
                return this.inputBCRReadStatus;
            }
            set
            {
                this.inputBCRReadStatus = value;
            }
        }
        public PortWIWO WaintIn
        {
            get
            {
                return this.WaitIn;
            }
            set
            {
                this.WaitIn = value;
            }
        }
        public PortWIWO WaitOut
        {
            get
            {
                return this.waitOut;
            }
            set
            {
                this.waitOut = value;
            }
        }
        public string CarrierId
        {
            get
            {
                return this.carrierId;
            }
            set
            {
                this.carrierId = value;
            }
        }
        public bool[] CarrierPresence
        {
            get
            {
                return this.carrierPresence;
            }
            set
            {
                this.carrierPresence = value;
            }
        }
        public CarrierElevType CarrierElevType
        {
            get
            {
                return this.carrierElevType;
            }
            set
            {
                this.carrierElevType = value;
            }
        }
        public bool IsOutputEnable
        {
            get
            {
                return this.isOutputEnable;
            }
            set
            {
                this.isOutputEnable = value;
            }
        }
        public bool IsPortDirChangeEnable
        {
            get
            {
                return this.isPortDirChangeEnable;
            }
            set
            {
                this.isPortDirChangeEnable = value;
            }
        }
        public bool IsOutPutRequestOK
        {
            get
            {
                return this.isOutPutRequestOK;
            }
            set
            {
                this.isOutPutRequestOK = value;
            }
        }
        public bool IsOutPutRequestNG
        {
            get
            {
                return this.isOutPutRequestNG;
            }
            set
            {
                this.isOutPutRequestNG = value;
            }
        }
        public DateTime WaitInTime
        {
            get
            {
                return this.waitInTime;
            }
            set
            {
                this.waitInTime = value;
            }
        }
        public bool IsUSECVWaitTimeOut
        {
            get
            {
                return this.isUSECVWaitTimeOut;
            }
            set
            {
                this.isUSECVWaitTimeOut = value;
            }
        }
        public bool IsUSEOfflineAutoCMD
        {
            get
            {
                return this.isUSEOfflineAutoCMD;
            }
            set
            {
                this.isUSEOfflineAutoCMD = value;
            }
        }

        public string PortPriority
        {
            get
            {
                return this.portPrity;
            }
            set
            {
                this.portPrity = value;
            }
        }
        public string OfflineAutoCMD_DestPort
        {
            get
            {
                return this.offlineAutoCMD_DestPort;
            }
            set
            {
                this.offlineAutoCMD_DestPort = value;
            }
        }
        public string RptAlarmID
        {
            get
            {
                string result;
                if (string.IsNullOrEmpty(this.rptAlarmID))
                {
                    result = "0";
                }
                else
                {
                    result = this.rptAlarmID;
                }
                return result;
            }
        }
        public string RptAlarmText
        {
            get
            {
                return this.rptAlarmText;
            }
        }
        public Observable _I_BUFFERMATERIALPRESENCE
        {
            get
            {
                return base.Observables["BUFFERMATERIALPRESENCE"];
            }
        }
        //PORT口禁用启用切换完成上报
        public Observable _I_ENABLEMODECHANGECP
        {
            get
            {
                return base.Observables["ENABLEMODECHANGECP"];
            }
        }
        //PORT口禁用启用切换完成回复
        public bool _O_ENABLEMODECHANGECPRPY
        {
            set
            {
                base.Observables["ENABLEMODECHANGECPRPY"].AsBoolean = value;
            }
        }
        //PORT口搬送模式上报(MANU/AGV/MGV)
        public Observable _I_PORTOPERATIONMODE
        {
            get
            {
                return base.Observables["PORTOPERATIONMODE"];
            }
        }
        //PORT口搬送模式切换请求
        public bool _O_PORTOPERATIONMODEREQ
        {
            set
            {
                base.Observables["PORTOPERATIONMODEREQ"].AsBoolean = value;
            }
        }
        //PORT口搬送模式切换回复
        public Observable _I_PORTOPERATIONMODERPY
        {
            get
            {
                return base.Observables["PORTOPERATIONMODERPY"];
            }
        }
        //PORT口搬送模式代码(MANU/AGV/MGV)
        public short _O_PORTOPERATIONMODECODE
        {
            set
            {
                base.Observables["PORTOPERATIONMODECODE"].AsShort = value;
            }
        }
        //PORT口取料模式上报
        public Observable _I_PORTMANUALMODE
        {
            get
            {
                return base.Observables["PORTMANUALMODE"];
            }
        }
        /*        public Observable _I_INOUTPUTMODE
                {
                    get
                    {
                        return base.Observables["INOUTPUTMODE"];
                    }
                }*/
        public Observable _I_PORTMODECODEREPORT
        {
            get
            {
                return base.Observables["PORTMODECODEREPORT"];
            }
        }
        //PORT入料扫码完成上报
        public Observable _I_INPUTBCRREADDOWN
        {
            get
            {
                return base.Observables["INPUTBCRREADDOWN"];
            }
        }

        //PORT入料扫码完成回复
        public bool _O_INPUTBCRREADDOWNRPY
        {
            set
            {
                base.Observables["INPUTBCRREADDOWNRPY"].AsBoolean = value;
            }
        }
        //Port模式能否改变
        public Observable _I_PORTMODECHANGEENABLE
        {
            get
            {
                return base.Observables["PORTMODECHANGEENABLE"];
            }
        }
        //Port模式切换请求
        public bool _O_PORTMODEREQ
        {
            set
            {
                base.Observables["PORTMODEREQ"].AsBoolean = value;
            }
        }
        /// <summary>
        /// MGVPort物料验证结果OK
        /// </summary>
        public bool _O_BCRVERIFYOK
        {
            set
            {
                base.Observables["BCRVERIFYOK"].AsBoolean = value;
            }
        }
        //PORT入料扫码完成上报
        public Observable _I_BCRVERIFYOKRPY
        {
            get
            {
                return base.Observables["BCRVERIFYOKRPY"];
            }
        }
        /// <summary>
        /// MGVPort物料验证结果NG
        /// </summary>
        public bool _O_BCRVERIFYNG
        {
            set
            {
                base.Observables["BCRVERIFYNG"].AsBoolean = value;
            }
        }
        //Port模式切换请求回复
        public Observable _I_PORTMODEREQREPLY
        {
            get
            {
                return base.Observables["PORTMODEREQREPLY"];
            }
        }
        //Port模式代码
        public short _O_PORTMODECODE
        {
            set
            {
                base.Observables["PORTMODECODE"].AsShort = value;
            }
        }
        //PORT口能否排出
        public Observable _I_OUTPUTENABLE
        {
            get
            {
                return base.Observables["OUTPUTENABLE"];
            }
        }
        //PORT出料扫码完成上报
        public Observable _I_OUTPUTBCRREADDOWN
        {
            get
            {
                return base.Observables["OUTPUTBCRREADDOWN"];
            }
        }
        //PORT出料扫码完成回复
        public bool _O_OUTPUTBCRREADDOWNRPY
        {
            set
            {
                base.Observables["OUTPUTBCRREADDOWNRPY"].AsBoolean = value;
            }
        }
        //PORT出料扫码结果
        public Observable _I_OUTPUTBCRREADRESULT
        {
            get
            {
                return base.Observables["OUTPUTBCRREADRESULT"];
            }
        }
        //PORT出料扫码结果
        public short I_OUTPUTBCRREADRESULT
        {
            get
            {
                return base.Observables["OUTPUTBCRREADRESULT"].AsShort;
            }
        }
        //BCR禁用使用模式(ENABLE/DISABLE)
        public Observable _I_BCRENABLEMODE
        {
            get
            {
                return base.Observables["BCRENABLEMODE"];
            }
        }
        //BCR禁用使用模式切换
        public bool _O_BCRENABLEREQ
        {
            set
            {
                base.Observables["BCRENABLEREQ"].AsBoolean = value;
            }
        }
        //BCR禁用使用模式切换回复
        public Observable _I_BCRENABLERPY
        {
            get
            {
                return base.Observables["BCRENABLERPY"];
            }
        }
        //BCR禁用使用模式切换代码(ENABLE/DISABLE)
        public short _O_BCRENABLECODE
        {
            set
            {
                base.Observables["BCRENABLECODE"].AsShort = value;
            }
        }
        //PIO交互信号
        public Observable _I_PORTPIO
        {
            get
            {
                return base.Observables["PORTPIO"];
            }
        }
        public short _I_PORTPIOVALUE
        {
            get
            {
                return base.Observables["PORTPIO"].AsShort;
            }
        }
        public Observable _I_SENSORIO
        {
            get
            {
                return base.Observables["SENSORIO"];
            }
        }
        public short _I_SENSORIOVALUE
        {
            get
            {
                return base.Observables["SENSORIO"].AsShort;
            }
        }
        public Observable _I_PORTSTATUS
        {
            get
            {
                return base.Observables["PORTSTATUS"];
            }
        }
        public Observable _I_MATERIALRUNRPY
        {
            get
            {
                return base.Observables["MATERIALRUNRPY"];
            }
        }
        //PORT等待进入
        public Observable _I_WAITIN
        {
            get
            {
                return base.Observables["WAITIN"];
            }
        }
        //PORT等待出去
        public Observable _I_WAITOUT
        {
            get
            {
                return base.Observables["WAITOUT"];
            }
        }
        public bool _I_MATERIALRUNREQ
        {
            set
            {
                base.Observables["MATERIALRUNREQ"].AsBoolean = value;
            }
        }
        public bool O_BIDIRECTIONMODEREQ
        {
            set
            {
                this.isBIDIRECTIONMODEREQ = value;
                base.Observables["BIDIRECTIONMODEREQ"].AsBoolean = value;
            }
        }
        public string I_BUFFERMATERIALID
        {
            get
            {
                return base.Observables["BUFFERMATERIALID"].AsString;
            }
            set
            {
                base.Observables["BUFFERMATERIALID"].AsString = value;
            }
        }
        public string IO_CSTIDBUFFER1
        {
            get
            {
                return base.Observables["CSTIDBUFFER1"].AsString;
            }
            set
            {
                base.Observables["CSTIDBUFFER1"].AsString = value;
            }
        }
        public bool O_DOWNREQ
        {
            set
            {
                this.isDownReqeust = value;
                base.Observables["DOWNREQ"].AsBoolean = value;
            }
        }

        public bool O_MANUALMATERIALID
        {
            set
            {
                base.Observables["MANUALMATERIALID"].AsBoolean = value;
            }
        }
        public bool O_FAULTRESET
        {
            set
            {
                this.isFAULTRESET = value;
                base.Observables["FAULTRESET"].AsBoolean = value;
            }
        }
        public bool O_INPUTMODEREQ
        {
            set
            {
                this.isINPUTMODEREQ = value;
                base.Observables["INPUTMODEREQ"].AsBoolean = value;
            }
        }
        public bool O_INPUTPORTBCRSET
        {
            set
            {
                this.isINPUTPORTBCRSET = value;
                base.Observables["INPUTPORTBCRSET"].AsBoolean = value;
            }
        }
        public bool O_INPUTRFREADDONEACK
        {
            set
            {
                base.Observables["INPUTRFREADDONEACK"].AsBoolean = value;
            }
        }
        public bool O_OUTPUTMODEREQ
        {
            set
            {
                this.isOUTPUTMODEREQ = value;
                base.Observables["OUTPUTMODEREQ"].AsBoolean = value;
            }
        }
        public bool O_OUTPUTRFREADDONEACK
        {
            set
            {
                base.Observables["OUTPUTRFREADDONEACK"].AsBoolean = value;
            }
        }
        public bool O_RUNREQ
        {
            set
            {
                this.isRunReqeust = value;
                base.Observables["RUNREQ"].AsBoolean = value;
            }
        }
        /// <summary>
        /// PORT口禁用启用切换请求
        /// </summary>
        public bool O_ENABLEMODECHANGE
        {
            set
            {
                base.Observables["ENABLEMODECHANGE"].AsBoolean = value;
            }
        }
        //---------------------------------------------------------------------------------VERSION-------------------------------------------------------
        //PORT入料扫码结果
        public short I_INPUTBCRREADRESULT
        {
            get
            {
                return base.Observables["INPUTBCRREADRESULT"].AsShort;
            }
        }
        //Port模式上报代码
        public short I_PORTMODECODEREPORT
        {
            get
            {
                return base.Observables["PORTMODECODEREPORT"].AsShort;
            }
        }
        /// <summary>
        /// 获取Vid值,返回的字典，键为字段名
        /// </summary>
        /// <returns></returns>
        public Dictionary<string, string> getVidValueForHost()
        {
            Dictionary<string, string> VidValue = new Dictionary<string, string>();
            VidValue.Add("LifterName", this.LftSem.HostID);
            VidValue.Add("LifterUnitID", this.HostID);
            VidValue.Add("CarrierID", this.CarrierId);
            VidValue.Add("CarrierLoc", this.HostID);
            VidValue.Add("PortIDi", this.HostID);
            VidValue.Add("PortStatei", ((int)this.portStateForAim).ToString());
            VidValue.Add("PortInOutType", ((int)GetAimLifertPortInOutType()).ToString());
            VidValue.Add("PortAccessMode", ((int)this.operationModeForAIM).ToString());
            VidValue.Add("IDReadStatus", ((int)this.inputBCRReadStatus).ToString());
            VidValue.Add("PortType", this.LifterPortType.ToString());
            VidValue.Add("HandOffType", ((int)this.enumPortManualMode).ToString());
            VidValue.Add("CarrierHandOffType", "0");
            return VidValue;
        }
        public bool UseDestPortFlag { get => useDestPortFlag; set => useDestPortFlag = value; }

        public bool UseChange { get => portUse; set => portUse = value; }
        public int Floor { get => floor; set => floor = value; }
        public PortWIWO WaitIn { get => waitIn; set => waitIn = value; }
        public PortType LifterPortType { get => lifterPortType; set => lifterPortType = value; }
        public enumLifterPortOperationModeForAIM OperationModeForAIM 
        {
            get 
            {
                return operationModeForAIM;
            }
            set 
            {
                if (this.operationModeForAIM != value)
                {
                    operationModeForAIM = value;
                    this.LftSem.SecsDriver.SendMessage("S6F11", "406", this);

                    //Port关联的内部CVPort是否需要上报
                    foreach (ConveyorBuffer conveyorBuffer in this.lftSem.ConveyorBuffers.Values)
                    {
                        if (conveyorBuffer.LifterPortID.Equals(this.elementId))
                        {
                            if (conveyorBuffer.IsReportHost)
                            {
                                conveyorBuffer.CVAccessModeForHost = "1";//((int)value).ToString(); //内测Port固定上报AUTO模式
                                this.LftSem.SecsDriver.SendMessage("S6F11", "406", conveyorBuffer);
                                string msg = string.Format("改变Port[{0}]操作模式为:[{1}]", conveyorBuffer.HostID, HandOffType.ValueToString(this.PortHandoffType));
                                LogHelper.loggerInfo(msg);
                            }
                        }
                    }
                }
            }
        }
        public enumBCREnableMode BCREnableMode { get => bcrEnableMode; set => bcrEnableMode = value; }
        public bool IsCombine { get => isCombine; set => isCombine = value; }
        public bool IsHostCommandTimeOut { get => isHostCommandTimeOut; set => isHostCommandTimeOut = value; }

        public LifterPort()
        {
        }
        public LifterPort(string elementID, SubSystemType subType, string ownerId, string Equipmentname, string assemblyName, string plcID, string hostID, HandOffType portHandOffType, PortType lifterPortType, ElevType portElevType, short portSize, bool isCombine, bool isNextLocation, int Floor)
            : base(elementID, SubSystemType.LIFTERPORT, ownerId, assemblyName, "Lifter.Device.Unit.LifterPort", plcID, hostID)
        {
            this.portHandoffType = portHandOffType;
            this.LifterPortType = lifterPortType;
            this.portElevType = portElevType;
            this.portSize = (int)portSize;
            this.IsCombine = isCombine;
            this.isNextLocation = isNextLocation;
            this.Floor = Floor;
        }
        protected override int Add(DBConnection theDB)
        {
            int result = 0;
            try
            {
                base.Add(theDB);
                PreparedSqlParameter preparedSqlParameter = theDB.GetPreparedSqlParameter();
                preparedSqlParameter.SetVarChar("ID", base.ID);
                SqlDataReader sqlDataReader = theDB.ExecuteQuery("select * from LifterPort where ID =@ID", preparedSqlParameter);
                if (sqlDataReader.Read())
                {
                    LogHelper.loggerInfo("LifterPort.add,[" + base.ID + "]already Exist");
                }
                else
                {
                    PreparedSqlParameter preparedSqlParameter2 = theDB.GetPreparedSqlParameter();
                    preparedSqlParameter2.SetVarChar("ID", base.ID);
                    preparedSqlParameter2.SetVarChar("HANDOFFTYPE", HandOffType.ValueToString(this.portHandoffType));
                    preparedSqlParameter2.SetVarChar("PORTTYPE", PortType.ValueToString(this.LifterPortType));
                    preparedSqlParameter2.SetVarChar("ELEVTYPE", ElevType.ValueToString(this.portElevType));
                    preparedSqlParameter2.SetInt("PORTSIZE", this.portSize);
                    preparedSqlParameter2.SetChar("ISCOMBINE", this.IsCombine ? "T" : "F");
                    preparedSqlParameter2.SetChar("ISNEXTLOC", this.isNextLocation ? "T" : "F");
                    preparedSqlParameter2.SetVarChar("FLOOR", this.Floor.ToString());
                    result = theDB.ExecuteUpdate("insert into LifterPort (ID, HANDOFFTYPE, PORTTYPE,ELEVTYPE,PORTSIZE,ISCOMBINE,ISNEXTLOC,EXCEPTIONFLOOR ) values (@ID,@HANDOFFTYPE,@PORTTYPE,@ELEVTYPE,@PORTSIZE,@ISCOMBINE,@ISNEXTLOC,@EXCEPTIONFLOOR)", preparedSqlParameter2);
                }
            }
            catch (SqlException ex)
            {
                LogHelper.loggerError("LifterPort.add流程报错",ex);
                throw ex;
            }
            return result;
        }
        protected override void Delete(DBConnection theDB)
        {
            try
            {
                base.Delete(theDB);
                PreparedSqlParameter preparedSqlParameter = theDB.GetPreparedSqlParameter();
                preparedSqlParameter.SetVarChar("ID", base.ID);
                theDB.ExecuteUpdate("delete from LifterPort where ID =@ID", preparedSqlParameter);
            }
            catch (SqlException ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// 初始化LifterPort信息
        /// </summary>
        /// <param name="theDB"></param>
        protected override void Load(DBConnection theDB)
        {
            try
            {
                base.Load(theDB);//加载LocationUnit信息
                PreparedSqlParameter preparedSqlParameter = theDB.GetPreparedSqlParameter();
                preparedSqlParameter.SetVarChar("ID", this.elementId);
                SqlDataReader sqlDataReader = theDB.ExecuteQuery("select * from LifterPort where ID =@ID", preparedSqlParameter);
                if (sqlDataReader.Read())
                {
                    base.ID = (string)sqlDataReader["ID"];
                    this.portHandoffType = HandOffType.StringToValue((string)sqlDataReader["HANDOFFTYPE"]);
                    this.LifterPortType = PortType.StringToValue((string)sqlDataReader["PORTTYPE"]);
                    this.portElevType = ElevType.StringToValue((string)sqlDataReader["ELEVTYPE"]);
                    this.portSize = (int)sqlDataReader["PORTSIZE"];
                    this.IsCombine = ((string)sqlDataReader["ISCOMBINE"]).Equals("T");
                    this.isNextLocation = ((string)sqlDataReader["ISNEXTLOC"]).Equals("T");
                    this.Floor = (int)sqlDataReader["FLOOR"];
                    if (this.isNextLocation)
                    {
                        this.nextLocationInfo = NextLocation.LoadNextLocationInfo(base.ID);
                    }
                }
                else
                {
                }
            }
            catch (SqlException ex)
            {
            }
            finally
            {
            }
        }
        protected override int Save(DBConnection theDB)
        {
            int result = 0;
            try
            {
                base.Save(theDB);
                if (base.LocationUnitDirtyFlag)
                {
                    base.LocationUnitDirtyFlag = false;
                    result = theDB.ExecuteUpdate(string.Concat(new object[]
                    {
                        "update LifterPort set\nHANDOFFTYPE='",
                        HandOffType.ValueToString(this.portHandoffType),
                        "',PORTTYPE='",
                        PortType.ValueToString(this.LifterPortType),
                        "',ELEVTYPE='",
                        ElevType.ValueToString(this.portElevType),
                        "',PORTSIZE='",
                        this.portSize,
                        "',ISCOMBINE='",
                        this.IsCombine ? "T" : "F",
                        "',FLOOR='",
                        this.Floor,
                        "',ISNEXTLOC='",
                        this.isNextLocation ? "T" : "F",
                        "'\nwhere ID = '",
                        base.ID,
                        "'"
                    }));
                }
            }
            catch (SqlException ex)
            {
                LogHelper.loggerError("LifterPort.save发生错误",ex);
            }
            return result;
        }
        public override void Init()
        {
            base.Init();
            this.AddSubscribe();
            this.CimAllCmdReset();
        }
        public override void Startup()
        {
            base.Startup();
            if (GlobalCode.ProjectCode == enumLiftProject.BMDT)
            {
                string userDefinedPropertyValue = base.GetUserDefinedPropertyValue("USE_CV_WAIT_IN_TIME_OUT", "F", false);
                this.isUSECVWaitTimeOut = (userDefinedPropertyValue == "T");
                userDefinedPropertyValue = base.GetUserDefinedPropertyValue("USE_OFFLINE_AUTOCMD", "F", false);
                this.isUSEOfflineAutoCMD = (userDefinedPropertyValue == "T");
                userDefinedPropertyValue = base.GetUserDefinedPropertyValue("OFF_LINE_DEST_PORT", "", false);
                this.offlineAutoCMD_DestPort = userDefinedPropertyValue;
                userDefinedPropertyValue = base.GetUserDefinedPropertyValue("USE_DEST_PORT_FLAG", "F", false);
                this.useDestPortFlag = (userDefinedPropertyValue == "T");
                userDefinedPropertyValue = base.GetUserDefinedPropertyValue("PORT_PRIORITY", "F", false);
                this.portPrity = userDefinedPropertyValue;
                userDefinedPropertyValue = base.GetUserDefinedPropertyValue("USECHANGE", "T", true);
                this.UseChange = (userDefinedPropertyValue == "T");

                userDefinedPropertyValue = base.GetUserDefinedPropertyValue("BCR_ENABLEMODE", "F", true);
                this.BCREnableMode = (userDefinedPropertyValue == "T") ? enumBCREnableMode.ENABLE:enumBCREnableMode.DISABLE ;
            }
        }
        public override void Shutdown()
        {
            base.Shutdown();
        }
        public void AddSubscribe()
        {
            this._I_PORTMODECODEREPORT.ObservableValueChanged += new DelegateObservableValueChanged(this._I_PORTMODECODEREPORT_ObservableValueChanged);
            this._I_PORTMODECHANGEENABLE.ObservableValueChanged += new DelegateObservableValueChanged(this._I_PORTMODECHANGEENABLE_ObservableValueChanged);
            //this._I_MGVAGVMODE.ObservableValueChanged += new DelegateObservableValueChanged(this._I_MGVAGVMODE_ObservableValueChanged);
            this._I_OUTPUTENABLE.ObservableValueChanged += new DelegateObservableValueChanged(this._I_OUTPUTENABLE_ObservableValueChanged);
            this._I_OUTPUTBCRREADDOWN.ObservableValueChanged += new DelegateObservableValueChanged(this._I_OUTPUTBCRREADDOWN_ObservableValueChanged);
            this._I_INPUTBCRREADDOWN.ObservableValueChanged += new DelegateObservableValueChanged(this._I_INPUTBCRREADDOWN_ObservableValueChanged);
            this._I_PORTSTATUS.ObservableValueChanged += new DelegateObservableValueChanged(this._I_PORTSTATUS_ObservableValueChanged);
            this._I_MATERIALRUNRPY.ObservableValueChanged += new DelegateObservableValueChanged(this._I_MATERIALRUNRPY_ObservableValueChanged);
            this._I_WAITIN.ObservableValueChanged += new DelegateObservableValueChanged(this._I_WAITIN_ObservableValueChanged);
            this._I_WAITOUT.ObservableValueChanged += new DelegateObservableValueChanged(this._I_WAITOUT_ObservableValueChanged);
            this._I_BUFFERMATERIALPRESENCE.ObservableValueChanged += new DelegateObservableValueChanged(this._I_BUFFERMATERIALPRESENCE_ObservableValueChanged);
            this._I_ENABLEMODECHANGECP.ObservableValueChanged += new DelegateObservableValueChanged(this._I_ENABLEMODECHANGECP_ObservableValueChanged);
            this._I_PORTMODEREQREPLY.ObservableValueChanged += new DelegateObservableValueChanged(this._I_PORTMODEREQREPLY_ObservableValueChanged);
            this._I_PORTOPERATIONMODE.ObservableValueChanged += new DelegateObservableValueChanged(this._I_PORTOPERATIONMODE_ObservableValueChanged);
            this._I_PORTOPERATIONMODERPY.ObservableValueChanged += new DelegateObservableValueChanged(this._I_PORTOPERATIONMODERPY_ObservableValueChanged);
            this._I_BCRENABLEMODE.ObservableValueChanged += new DelegateObservableValueChanged(this._I_BCRENABLEMODE_ObservableValueChanged);
            this._I_BCRENABLERPY.ObservableValueChanged += new DelegateObservableValueChanged(this._I_BCRENABLERPY_ObservableValueChanged);
            this._I_PORTPIO.ObservableValueChanged += new DelegateObservableValueChanged(_I_PORTPIO_ObservableValueChanged);
            this._I_SENSORIO.ObservableValueChanged += new DelegateObservableValueChanged(_I_SENSORIO_ObservableValueChanged);
            this._I_PORTMANUALMODE.ObservableValueChanged += new DelegateObservableValueChanged(this._I_PORTMANUALMODE_ObservableValueChanged);
            this._I_BCRVERIFYOKRPY.ObservableValueChanged += new DelegateObservableValueChanged(_I_BCRVERIFYOKRPY_ObservableValueChanged);
            /*            foreach (string current in base.Observables.Keys)
                        {
                            base.Observables[current].ObservableLogEvent += new delegateObservableLogEvent(this.LifterPort_ObservableLogEvent);
                        }*/
        }

        private void _I_SENSORIO_ObservableValueChanged(object sender, object value)
        {
            try
            {
                int SensorIOData = Convert.ToInt32(value);
                //委托前端界面实时显示
                if (this.senserInfoDelegate != null)
                {
                    this.senserInfoDelegate(SensorIOData);
                }
            }
            catch (Exception ex)
            {
                LogHelper.loggerError("在方法_I_SENSORIO_ObservableValueChanged中报错", ex);
            }
        }

        private void _I_PORTPIO_ObservableValueChanged(object sender, object value)
        {
            try
            {
                int pioData = Convert.ToInt32(value);
                //委托前端界面实时显示
                if (this.pIODelegate != null)
                {
                    this.pIODelegate(pioData);
                }
                //PIO历史记录
                if (pioData < 0)
                {
                    this.PortPioUpadte(65536 + pioData);
                }
                else
                {
                    this.PortPioUpadte(pioData);
                }
            }
            catch (Exception ex)
            {
                LogHelper.loggerError("在方法_I_PORTPIO_ObservableValueChanged中报错", ex);
            }
            
        }
        public void PortPioUpadte(int PIOValue)
        {
            //如果值大于128，则表示正在进行交互
            if (PIOValue > 128)
            {
                PortPIODict.Add(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"),PIOValue);
            }
            else
            {
                if (PortPIODict.Count > 0)
                {
                    try
                    {
                        var valuesArray = PortPIODict.Values.ToArray();
                        var valueTimesArray = PortPIODict.Keys.ToArray();
                        string values = string.Join(",", valuesArray);
                        string valueTimes = string.Join(",", valueTimesArray);
                        //交互结束，记录到数据表中
                        DBConnection dBConnection = DBControl.GetConnection();
                        string sqlString = $"INSERT INTO PORTPIOHISTORY VALUES('{this.HostID}','{values}','{valueTimesArray[valueTimesArray.Length - 1]}','{valueTimesArray[0]}','{this.carrierId}','{valueTimes}')";
                        dBConnection.ExecuteUpdate(sqlString);
                        DBControl.RemoveDBConection(dBConnection);
                        PortPIODict.Clear();
                    }
                    catch (Exception ex)
                    {
                        PortPIODict.Clear();
                        LogHelper.loggerError("在PortPioUpadte方法中报错", ex);
                    }
                }
            }
        }
        private void _I_MATERIALRUNRPY_ObservableValueChanged(object sender, object value)
        {
            if ((bool)value)
            {
                LogHelper.loggerInfo($"Port[{this.HostID}]上报物料启动回复信号off");
                this._I_MATERIALRUNREQ = false;
            }
        }
        private void _I_PORTMANUALMODE_ObservableValueChanged(object sender, object value)
        {
            if ((bool)value)
            {
                LogHelper.loggerInfo($"Port[{this.HostID}]上报PORT口手动模式下取料信号置ON");
                this.enumPortManualMode = enumHandOfftype.MANUAL;
            }
            else
            {
                LogHelper.loggerInfo($"Port[{this.HostID}]上报PORT口手动模式下取料信号置OFF");
                this.enumPortManualMode = enumHandOfftype.AUTO;
            }
        }
        private void _I_BCRVERIFYOKRPY_ObservableValueChanged(object sender, object value)
        {
            if ((bool)value)
            {
                this._O_BCRVERIFYOK = false;
                LogHelper.loggerInfo("MCS验证OK,BCRVERIFYOK信号置OFF");
            }
        }
        /// <summary>
        /// Add by yanhgshl 2023/09/07
        /// Port口CV物料感应信号
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="value"></param>
        private void _I_BUFFERMATERIALPRESENCE_ObservableValueChanged(object sender, object value)
        {
            this.BUFFERMATERIALPRESENCE_ObservableValueChanged(sender, value, 1);
        }
        /// <summary>
        /// Port禁用启用上报
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="value"></param>
        private void _I_ENABLEMODECHANGECP_ObservableValueChanged(object sender, object value)
        {
            try
            {
                if ((bool)value)
                {
                    this._O_ENABLEMODECHANGECPRPY = true;
                }
                else
                {
                    this._O_ENABLEMODECHANGECPRPY = false;
                    if (this.UseChange)
                    {
                        this.SetUserDefinedPropertyValue("USECHANGE", "T", this.HostID);
                    }
                    else
                    {
                        this.SetUserDefinedPropertyValue("USECHANGE", "F", this.HostID);
                    }
                    this.InnerPublishEvent(LifterPortEvent.LifterPortEventType.INIT);
                }
            }
            catch
            {
            }
        }
        public void PortModeReq(enumLifterPortDirection portMode)
        {
            if (portMode == enumLifterPortDirection.IN)
            {
                this._O_PORTMODECODE = 1;
            }
            else if (portMode == enumLifterPortDirection.OUT)
            {
                this._O_PORTMODECODE = 2;
            }
            else
            {
                this._O_PORTMODECODE = 3;
            }
            this._O_PORTMODEREQ = true;
        }
        public void PortOperationModeCode(HandOffType handOffType)
        {
            if (handOffType == HandOffType.MGV)
            {
                this._O_PORTOPERATIONMODECODE = 0;
            }
            else if (handOffType == HandOffType.AGV)
            {
                this._O_PORTOPERATIONMODECODE = 1;
            }
            else
            {
                this._O_PORTOPERATIONMODECODE = 2;
            }
            this._O_PORTOPERATIONMODEREQ = true;
        }
        public void BCREnableModeMethod(bool bcrEnableMethod)
        {
            if (bcrEnableMethod)
            {
                this._O_BCRENABLECODE = 1;//启用
            }
            else
            {
                this._O_BCRENABLECODE = 2;//禁用
            }
            this._O_BCRENABLEREQ = true;
        }
        /// <summary>
        /// PORT模式切换请求回复
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="value"></param>
        private void _I_PORTMODEREQREPLY_ObservableValueChanged(object sender, object value)
        {
            try
            {
                if ((bool)value)
                {
                    this._O_PORTMODEREQ = false;
                }
            }
            catch
            {
            }
        }
        /// <summary>
        /// PORT口搬送模式上报(MGV/AGV/RGV)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="value"></param>
        private void _I_PORTOPERATIONMODE_ObservableValueChanged(object sender, object value)
        {
            try
            {
                switch ((short)value)
                {
                    case 1:
                        this.PortHandoffType = HandOffType.MGV;
                        break;
                    case 2:
                        this.PortHandoffType = HandOffType.AGV;
                        break;
                    case 3:
                        this.PortHandoffType = HandOffType.RGV;
                        break;
                }
                this.OnPortEventStateChange();
                string msg = string.Format("改变Port[{0}]操作模式为:[{1}]", this.HostID, HandOffType.ValueToString(this.PortHandoffType));
                LogHelper.loggerInfo(msg);
            }
            catch (Exception ex)
            {
                LogHelper.loggerError("在方法[_I_PORTOPERATIONMODE_ObservableValueChanged]中报错",ex);
            }
        }
        /// <summary>
        /// PORT口搬送模式切换回复
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="value"></param>
        private void _I_PORTOPERATIONMODERPY_ObservableValueChanged(object sender,object value)
        {
            try
            {
                if (Convert.ToBoolean(value) == true)
                {
                    this._O_PORTOPERATIONMODEREQ = false;
                }
            }
            catch
            {
            }
        }
        /// <summary>
        /// BCR禁用使用模式(ENABLE/DISABLE)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="value"></param>
        private void _I_BCRENABLEMODE_ObservableValueChanged(object sender,object value)
        {
            try
            {
                if (Convert.ToBoolean(value) == true)
                {
                    this.bcrEnableMode = enumBCREnableMode.ENABLE;
                    this.SetUserDefinedPropertyValue("BCR_ENABLEMODE", "T", this.HostID);
                }
                else
                {
                    this.bcrEnableMode = enumBCREnableMode.DISABLE;
                    this.SetUserDefinedPropertyValue("BCR_ENABLEMODE", "F", this.HostID);
                }
                this.InnerPublishEvent(LifterPortEvent.LifterPortEventType.INIT);
            }
            catch
            {
            }
        }
        /// <summary>
        /// BCR禁用使用模式切换回复
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="value"></param>
        private void _I_BCRENABLERPY_ObservableValueChanged(object sender,object value)
        {
            try
            {
                if (Convert.ToBoolean(value) == true)
                {
                    this._O_BCRENABLEREQ = false;
                }
            }
            catch
            {
            }
        }
        /// <summary>
        /// PORTBUFFER上面是否有实物信号
        /// 当实物流到buffer上触发ON信号，实物流走触发OFF信号
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="value"></param>
        /// <param name="idx"></param>
        private void BUFFERMATERIALPRESENCE_ObservableValueChanged(object sender, object value, int idx)
        {
            try
            {
                bool flag = (bool)value;
                LogHelper.loggerInfo($"Port[{this.HostID}]上报在籍信号为[{flag}]");
                //判断buffer上是否有实物
                if (this.carrierPresence[idx] != flag)
                {
                    //给对应的buffercarrierPresence赋值，有实物赋值true，无实物赋值false
                    this.carrierPresence[idx] = flag;
                    if (flag)
                    {
                        //实物流到buffer上
                        this.OnBufferMaterialPresenceOn(idx);
                    }
                    else
                    {
                        //实物从buffer流走
                        this.OnBufferMaterialPresenceOff(idx);
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.loggerError("在[BUFFERMATERIALPRESENCE_ObservableValueChanged]方法中报错，Port口在位信号流程异常",ex);
            }
        }
        /// <summary>
        /// Port模式能否改变
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="value"></param>
        private void _I_PORTMODECHANGEENABLE_ObservableValueChanged(object sender, object value)
        {
            try
            {
                if (Convert.ToBoolean(value) == true)
                {
                    this.IsPortDirChangeEnable = true;
                }
                else
                {
                    this.IsPortDirChangeEnable = false;
                }
                if (PortInfomationDetail.PortInformationDetailbyName.Count > 0)
                {
                    PortInfomationDetail portInformation = PortInfomationDetail.PortInformationDetailbyName[elementId];
                    if (portInformation != null)
                    {
                        portInformation.UpdateDelegateEvent();
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.loggerError("在[_I_PORTMODECHANGEENABLE_ObservableValueChanged]方法中，PortMode改变流程异常", ex);
            }
        }
        /// <summary>
        /// 扫码完成信号上报
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="value"></param>
        private void _I_INPUTBCRREADDOWN_ObservableValueChanged(object sender, object value)
        {
            LogHelper.loggerInfo($"Port{this.HostID}上报扫码完成信号[{(bool)value}]");
            if ((bool)value)
            {
                try
                {
                    this.OnIDReadDone();
                }
                catch (Exception ex)
                {
                    LogHelper.loggerError("在[_I_INPUTBCRREADDOWN_ObservableValueChanged]方法中报错，物料扫码完成上报流程异常", ex);
                }
                this._O_INPUTBCRREADDOWNRPY = true;
                LogHelper.loggerInfo($"Port{this.HostID}扫码完成回复信号[true]");
            }
            else
            {
                //判断是否PC给PLC设定CSTID,默认值为false
                this._O_INPUTBCRREADDOWNRPY = false;
                LogHelper.loggerInfo($"Port{this.HostID}扫码完成回复信号[false]");
            }
        }
        /// <summary>
        /// PORT模式上报(MGV/AGV/RGV)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="value"></param>
        /*        private void _I_INOUTPUTMODE_ObservableValueChanged(object sender, object value)
                {
                    try
                    {
                        if ((bool)value)
                        {
                            short Code = this.I_PORTMODECODEREPORT;
                            switch (Code)
                            {
                                case 0:
                                    this.portInOutMode = enumLifterPortDirection.IN;
                                    break;
                                case 1:
                                    this.portInOutMode = enumLifterPortDirection.OUT;
                                    break;
                                case 2:
                                    this.portInOutMode = enumLifterPortDirection.BOTH;
                                    break;
                                default:
                                    break;
                            }
                        }
                        this.OnPortHandOffTypeChange();
                    }
                    catch (Exception ex)
                    {
                        StatisticsCollector.TriggerOccured("RUN_TIME_EXCEPTION", "CORE_EXCETPION", new RunTimeExceptionStatisticsCollectorData("LifterPort", "LifterPort_ObservableLogEvent", "", ex.ToString(), ex.StackTrace.ToString()));
                    }
                }*/
        /// <summary>
        /// PORT模式代码上报（IN/OUT/BOTH）
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="value"></param>
        private void _I_PORTMODECODEREPORT_ObservableValueChanged(object sender, object value)
        {
            try
            {
                switch ((short)value)
                {
                    case 1:
                        this.PortInOutMode = enumLifterPortDirection.IN;
                        this.PortAIMInOutType = enumAIMLifertPortInOutType.INPUT;
                        break;
                    case 2:
                        this.portInOutMode = enumLifterPortDirection.OUT;
                        this.PortAIMInOutType = enumAIMLifertPortInOutType.OUTPUT;
                        break;
                    case 3:
                        this.portInOutMode = enumLifterPortDirection.BOTH;
                        this.PortAIMInOutType = enumAIMLifertPortInOutType.BOTH;
                        break;
                    default:
                        break;
                }
                this.OnPortHandOffTypeChange();
                this.ChangeCVTypeByPortDrict(this.PortInOutMode);
            }
            catch (Exception ex)
            {
                LogHelper.loggerError("在[_I_PORTMODECODEREPORT_ObservableValueChanged]方法中报错，PortInOut方向切换流程中异常", ex);
            }
        }
        /// <summary>
        /// 切换Port口方向时，改变CV的类型
        /// </summary>
        private void ChangeCVTypeByPortDrict(enumLifterPortDirection portDirct)
        {
            try
            {
                DBConnection dBConnection = DBControl.GetConnection();
                string sqlString = string.Format("SELECT * FROM CV WHERE PORT = '{0}'", this.elementId);
                SqlDataReader sqlDataReader = dBConnection.ExecuteQuery(sqlString);
                while (sqlDataReader.Read())
                {
                    string cvType = sqlDataReader["CVTYPE"].ToString();
                    string CVID = sqlDataReader["NAME"].ToString();
                    if (!string.IsNullOrWhiteSpace(cvType) &&  !"NULL".Equals(cvType.Trim().ToUpper()))
                    {
                        
                        if (portDirct == enumLifterPortDirection.IN && cvType.Equals(ConveyorBuffer.Constants.CVLOAD))
                        {
                            DBConnection dBConnectionUpdate = DBControl.GetConnection();
                            //将cvType改变为CVUNLOAD类型
                            string updateSqlString = string.Format("UPDATE CV SET CVTYPE = '{0}' WHERE PORT = '{1}' AND CVTYPE != ''", ConveyorBuffer.Constants.CVUNLOAD, this.elementId);
                            dBConnectionUpdate.ExecuteUpdate(updateSqlString);
                            DBControl.RemoveDBConection(dBConnectionUpdate);

                            //更新更新CV字典集合，同步数据库
                            foreach (ConveyorBuffer conveyorBuffer in this.LftSem.ConveyorBuffers.Values)
                            {
                                if (conveyorBuffer.ElementId.Trim().Equals(CVID.Trim()))
                                {
                                    conveyorBuffer.Cvtype = ConveyorBuffer.Constants.CVUNLOAD;
                                    //更加CV方向更新CV的创建指令控件
                                    LoadMainLayout.getLoadMainLayout().DoDelegateUpdateCVControl(conveyorBuffer.ElementId, ConveyorBuffer.Constants.CVUNLOAD);
                                    //上报MCS CV方向切换事件
                                    if (conveyorBuffer.IsReportHost)
                                    {
                                        this.LftSem.SecsDriver.SendMessage("S6F11", "405", conveyorBuffer);
                                    }
                                }
                            }
                        }
                        if (portDirct == enumLifterPortDirection.OUT && cvType.Equals(ConveyorBuffer.Constants.CVUNLOAD))
                        {
                            DBConnection dBConnectionUpdate = DBControl.GetConnection();
                            //将cvType改变为CVLOAD类型
                            string updateSqlString = string.Format("UPDATE CV SET CVTYPE = '{0}' WHERE PORT = '{1}' AND CVTYPE != ''", ConveyorBuffer.Constants.CVLOAD, this.elementId);
                            dBConnectionUpdate.ExecuteUpdate(updateSqlString);
                            DBControl.RemoveDBConection(dBConnectionUpdate);

                            //更新更新CV字典集合，同步数据库
                            foreach (ConveyorBuffer conveyorBuffer in this.LftSem.ConveyorBuffers.Values)
                            {
                                if (conveyorBuffer.ElementId.Trim().Equals(CVID.Trim()))
                                {
                                    conveyorBuffer.Cvtype = ConveyorBuffer.Constants.CVLOAD;
                                    //更加CV方向更新CV的创建指令控件
                                    LoadMainLayout.getLoadMainLayout().DoDelegateUpdateCVControl(conveyorBuffer.ElementId, ConveyorBuffer.Constants.CVLOAD);
                                    //上报MCS CV方向切换事件
                                    if (conveyorBuffer.IsReportHost)
                                    {
                                        this.LftSem.SecsDriver.SendMessage("S6F11", "405", conveyorBuffer);
                                    }
                                }
                            }
                        }
                    }
                }
                if (sqlDataReader != null)
                {
                    sqlDataReader.Close();
                }
                DBControl.RemoveDBConection(dBConnection);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        private void _I_OUTPUTENABLE_ObservableValueChanged(object sender, object value)
        {
            this.IsOutputEnable = (bool)value;
        }
        /// <summary>
        /// 出Port口扫码完成上报
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="value"></param>
        private void _I_OUTPUTBCRREADDOWN_ObservableValueChanged(object sender, object value)
        {
            LogHelper.loggerInfo($"Port{this.HostID}上报出料扫码完成信号[{(bool)value}]");
            if ((bool)value)
            {
                try
                {
                    this.OnOutputIDReadDone();
                }
                catch (Exception ex)
                {
                    LogHelper.loggerError("在[_I_OUTPUTBCRREADDOWN_ObservableValueChanged]方法中报错，Output口扫码完成上报流程异常", ex);
                }
                this._O_OUTPUTBCRREADDOWNRPY = true;
                LogHelper.loggerInfo($"Port{this.HostID}出料扫码完成回复信号[true]");
            }
            else
            {
                this._O_OUTPUTBCRREADDOWNRPY = false;
                LogHelper.loggerInfo($"Port{this.HostID}出料扫码完成回复信号[false]");
            }
        }
        /// <summary>
        /// Port状态(idle,run,down)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="value"></param>
        private void _I_PORTSTATUS_ObservableValueChanged(object sender, object value)
        {
            try
            {
                enumPortStateForAim newPortStateForAim = enumPortStateForAim.InService;
                switch ((short)value)
                {
                    case 0:
                        this.LifterPortState = enumRIDState.DOWN;
                        newPortStateForAim = enumPortStateForAim.OutofService;
                        //this.CimAllCmdReset();
                        break;
                    case 1:
                        //this.CimCommandAndAckSetReset(LifterPort.enumCIMPortSetResetCase.RUN_REQ, false);
                        newPortStateForAim = enumPortStateForAim.InService;
                        this.LifterPortState = enumRIDState.IDLE;
                        break;
                    case 2:
                        //this.CimCommandAndAckSetReset(LifterPort.enumCIMPortSetResetCase.RUN_REQ, false);
                        newPortStateForAim = enumPortStateForAim.InService;
                        this.LifterPortState = enumRIDState.RUN;
                        break;
                }
                if (this.portStateForAim != newPortStateForAim)
                {
                    if (newPortStateForAim == enumPortStateForAim.InService)
                    {
                        this.LftSem.SecsDriver.SendMessage("S6F11", "401", this);
                        //Port对应的CVPort同步上报状态 add by ysl 2024/1/19
                        foreach (ConveyorBuffer conveyorBuffer in this.LftSem.ConveyorBuffers.Values)
                        {
                            if (conveyorBuffer.LifterPortID.Equals(this.elementId) && conveyorBuffer.IsReportHost)
                            {
                                this.LftSem.SecsDriver.SendMessage("S6F11", "401", conveyorBuffer);
                            }
                        }
                        this.portStateForAim = newPortStateForAim;
                        //如果Port口是In口，且物料绑定的指令是SourceNG状态,则恢复指令
                        if (this.PortInOutMode == enumLifterPortDirection.IN)
                        {
                            List<TransferWorkItem> sourceNGTransfers = this.lftSem.LDispatcher.GetTransferCommandByStatus(enumTransferState.SOURCENG);
                            foreach (TransferWorkItem transferWorkItem in sourceNGTransfers)
                            {
                                ConveyorBuffer conveyorBuffer = this.lftSem.GetConveyorBuffer(transferWorkItem.Source);
                                if (conveyorBuffer != null)
                                {
                                    if (this.elementId.Equals(conveyorBuffer.LifterPortID) && transferWorkItem.TransferState == enumTransferState.SOURCENG)
                                    {
                                        Carrier carrier = this.lftSem.GetCarrierByCarrierID(transferWorkItem.CarrierID);
                                        if (carrier != null)
                                        {
                                            transferWorkItem.TransferState = enumTransferState.LOADREQ;
                                            MainTransferQueuePanel mainTransferQueuePanel = (MainTransferQueuePanel)SimpleCache.GetObject("OperationForm", "MainTransferQueuePanel");
                                            mainTransferQueuePanel.UpdateDelegate();
                                        }
                                        else
                                        {
                                            LogHelper.loggerInfo($"任务[{transferWorkItem.CommandID}]恢复失败,指令绑定的物料不存在");
                                        }
                                    }
                                }
                                else
                                {
                                    LifterPort lifterPort = this.lftSem.GetLifterPort(transferWorkItem.Source);
                                    if (lifterPort != null && this.elementId.Equals(lifterPort.elementId) && transferWorkItem.TransferState == enumTransferState.SOURCENG)
                                    {
                                        Carrier carrier = this.lftSem.GetCarrierByCarrierID(transferWorkItem.CarrierID);
                                        if (carrier != null )
                                        {
                                            transferWorkItem.TransferState = enumTransferState.LOADREQ;
                                            MainTransferQueuePanel mainTransferQueuePanel = (MainTransferQueuePanel)SimpleCache.GetObject("OperationForm", "MainTransferQueuePanel");
                                            mainTransferQueuePanel.UpdateDelegate();
                                        }
                                        else
                                        {
                                            LogHelper.loggerInfo($"任务[{transferWorkItem.CommandID}]恢复失败,指令绑定的物料不存在");
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        this.LftSem.SecsDriver.SendMessage("S6F11", "402", this);
                        //Port对应的CVPort同步上报状态 add by ysl 2024/1/19
                        foreach (ConveyorBuffer conveyorBuffer in this.LftSem.ConveyorBuffers.Values)
                        {
                            if (conveyorBuffer.LifterPortID.Equals(this.elementId) && conveyorBuffer.IsReportHost)
                            {
                                this.LftSem.SecsDriver.SendMessage("S6F11", "402", conveyorBuffer);
                            }
                        }
                        this.portStateForAim = newPortStateForAim;
                        //如果Port口是In口，且有正在等待入料的指令，则将指令标记成SourceNg状态
                        if (this.PortInOutMode == enumLifterPortDirection.IN)
                        {
                            //获取当前Port口Load状态的指令
                            //获取所有的Load指令
                            List<TransferWorkItem> loadWorks = this.lftSem.LDispatcher.GetTransferCommandByStatus(enumTransferState.LOADREQ);
                            foreach (TransferWorkItem transferWorkItem in loadWorks)
                            {
                                ConveyorBuffer conveyorBuffer = this.lftSem.GetConveyorBuffer(transferWorkItem.Source);
                                if (conveyorBuffer != null)
                                {
                                    if (this.elementId.Equals(conveyorBuffer.LifterPortID) && transferWorkItem.TransferState != enumTransferState.ONSHUTTLE)
                                    {
                                        /*transferWorkItem.Dest = transferWorkItem.Source;
                                        this.lftSem.LDispatcher.CompleteJob(transferWorkItem.CommandID, enumTransferResult.SOURCE_INTERLOC_NG);*/
                                        transferWorkItem.TransferState = enumTransferState.SOURCENG;
                                        MainTransferQueuePanel mainTransferQueuePanel = (MainTransferQueuePanel)SimpleCache.GetObject("OperationForm", "MainTransferQueuePanel");
                                        mainTransferQueuePanel.UpdateDelegate();
                                    }
                                }
                                else
                                {
                                    LifterPort lifterPort = this.lftSem.GetLifterPort(transferWorkItem.Source);
                                    if (lifterPort != null && this.elementId.Equals(lifterPort.elementId) && transferWorkItem.TransferState != enumTransferState.ONSHUTTLE)
                                    {
                                        /*transferWorkItem.Dest = transferWorkItem.Source;
                                        this.lftSem.LDispatcher.CompleteJob(transferWorkItem.CommandID, enumTransferResult.SOURCE_INTERLOC_NG);*/
                                        transferWorkItem.TransferState = enumTransferState.SOURCENG;
                                        MainTransferQueuePanel mainTransferQueuePanel = (MainTransferQueuePanel)SimpleCache.GetObject("OperationForm", "MainTransferQueuePanel");
                                        mainTransferQueuePanel.UpdateDelegate();
                                    }
                                }
                            }
                        }
                    }
                }
                //根据Port状态，改变设备状态
/*                if (this.lifterPortState == enumRIDState.DOWN)
                {
                    if (LftSem.DeviceState != enumRIDState.DOWN)
                    {
                        LftSem.DeviceState = enumRIDState.DOWN;
                    }
                }
                else
                {
                    if (LftSem.DeviceState != enumRIDState.RUN)
                    {
                        LftSem.DeviceState = enumRIDState.RUN;
                    }
                }*/
                this.OnPortEventStateChange();
                string msg = string.Format("改变Port[{0}]状态为:[{1}]", this.HostID, this.LifterPortState);
                LogHelper.loggerInfo(msg);
            }
            catch (Exception ex)
            {
                LogHelper.loggerError("在[_I_PORTSTATUS_ObservableValueChanged]方法中报错，Port状态切换流程异常", ex);
            }
        }
        /// <summary>
        /// PLC触发WAITIN信号,PC上报HOST CarrierWaitIn事件
        /// 等待Host下达指令，若Host下达指令超时，则PC自动创建指令，上报Host
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="value"></param>
        private void _I_WAITIN_ObservableValueChanged(object sender, object value)
        {
            try
            {
                LogHelper.loggerInfo($"PORT[{this.HostID}] WAITIN 信号:" + (bool)value);
                if ((bool)value)
                {
                    this.CarrierId = this.I_BUFFERMATERIALID;
                    //是否在Port改变Port状态为WaitIn,并且上报MCS
                    if (this.IsCombine)
                    {
                        //给MCS上报CarrierWaitIn事件 
                        //判断当前port模式是否为IN模式
                        if (this.PortInOutMode != enumLifterPortDirection.IN)
                        {
                            string xMsg = "/" + base.HostID + "/W.I/在Output Port上发生了 W.I 事件.";
                            LogHelper.loggerInfo(xMsg);
                        }
                        else
                        {
                            Carrier carrier = Naming.GetCarrierManager().GetCarrier(this.CarrierId);
                            this.lftSem.SecsDriver.SendMessage("S6F11", "303", this, carrier);
                            string msg = string.Format("Port[{0}]上报MCS WaitIn事件", this.HostID);
                            LogHelper.loggerInfo(msg);
                            this._I_MATERIALRUNREQ = true;
                        }
                    }
                    else
                    {
                        this.OnWaitIn();
                    }
                }
                else
                {
                    this.WaitIn = PortWIWO.NONE;
                    this.WaitInTime = DateTime.MinValue;
                    this.OnWaitInOff();
                }
            }
            catch (Exception ex)
            {
                LogHelper.loggerError("在[_I_WAITIN_ObservableValueChanged]方法中报错，Port上报Waitin流程异常", ex);
            }
        }
        private void _I_WAITOUT_ObservableValueChanged(object sender, object value)
        {
            try
            {
                LogHelper.loggerInfo($"Port[{this.HostID}] WAITOUT 信号:" + (bool)value);
                if ((bool)value)
                {
                    this.CarrierId = this.I_BUFFERMATERIALID;
                    //判断物料是否为空
                    if (this.CarrierId == null && this.CarrierId == "")
                    {
                        //记录log，或弹窗提醒（OutPort物料为空）
                        this.CarrierId = this.I_BUFFERMATERIALID;
                    }
                    Carrier carrier = Naming.GetCarrierManager().GetCarrier(this.CarrierId);
                    //判断物料信息是否为空
                    if (carrier == null)
                    {
                        this.LftSem.InstallMaterial(this.CarrierId, base.HostID, "", CarrierState.WAITOUT, CarrierType.CA_TRAY, this.InputBCRReadStatus.ToString(), Carrier.MaterialCreateTypeConstants.AUTO);
                        LogHelper.loggerInfo(string.Format("出料Port[{0}]没有物料信息，重新生成物料信息，物料物料ID为:[{1}]", this.HostID, this.CarrierId));
                    }
                    //是否在Port改变Port状态为WaitIn,并且上报MCS
                    if (this.IsCombine)
                    {
                        //给MCS上报CarrierWaitIn事件 
                        //判断port口模式是否为out模式
                        if (this.PortInOutMode != enumLifterPortDirection.OUT)
                        {
                            string xMsg = string.Format("Port[{0}]不是OutPut模式，无法执行WaitOut操作");
                            LogHelper.loggerInfo(xMsg);
                        }
                        else
                        {
                            if (carrier != null)
                            {
                                Console.WriteLine("PortWaitOut: ID" + carrier.CarrierId);
                                this.lftSem.SecsDriver.SendMessage("S6F11", "304", this, carrier);
                                LogHelper.loggerInfo(string.Format("Port[{0}]上报WaitOut(304)事件，物料ID为:[{1}]",this.HostID,carrier.CarrierId));
                            }
                            else
                            {
                                LogHelper.loggerInfo("上报MCS WaitOut事件时，物料信息为空");
                                Console.WriteLine("上报MCS WaitOut事件时，物料信息为空");
                            }
                        }
                    }
                    else
                    {
                        this.WaitOut = PortWIWO.WAIT_OUT;
                        this.OnWaitOutOn();
                    }
                }
                else
                {
                    this.WaitOut = PortWIWO.NONE;
                    this.OnWaitOutOff();
                }
            }
            catch (Exception ex)
            {
                LogHelper.loggerError("在[_I_WAITOUT_ObservableValueChanged]方法中报错，Port上报WaitOut流程异常", ex);
            }
        }

        /// <summary>
        /// 扫码完成信号上报，触发事件
        /// 创建物料对象，绑定当前位置，设置物料状态
        /// </summary>
        private void OnIDReadDone()
        {
            //判断Port模式
            if (this.PortHandoffType == HandOffType.MGV)
            {
                //从PLC获取扫码结果-- 1 =》扫码OK； 2=》扫码失败
                //扫码成功
                if (this.I_INPUTBCRREADRESULT == 1)
                {
                    this.MGVPortBCRReadSuccess();
                }
                else if (this.I_INPUTBCRREADRESULT == 2) //扫码失败
                {
                    //this.MGVPortBCRReadFail();
                    //临时程序
                    this.AGVPortBCRReadFail();
                }
                else
                {
                    //其他case; 弹窗提醒扫码结果上报错误
                }
            }
            else
            {
                //从PLC获取扫码结果-- 1 =》扫码OK； 2=》扫码失败
                //扫码成功
                if (this.I_INPUTBCRREADRESULT == 1)
                {
                    this.AGVPortBCRReadSuccess();
                }
                else if (this.I_INPUTBCRREADRESULT == 2) //扫码失败
                {
                    this.AGVPortBCRReadFail();
                }
                else if (this.I_INPUTBCRREADRESULT == 3)//扫码重复
                {
                    this.AGVPortBCRReadDup();
                }
                else
                {
                    //其他case; 弹窗提醒扫码结果上报错误
                }
            }
            //保存扫码记录，插入数据库
            //
            //
            //
        }
        /// <summary>
        /// 出料扫码完成逻辑
        /// </summary>
        private void OnOutputIDReadDone()
        {
            //从PLC获取扫码结果-- 1 =》扫码OK； 2=》扫码失败
            //扫码成功
            if (this.I_OUTPUTBCRREADRESULT == 1)
            {
                this.AGVPortOutputBCRReadSuccess();
            }
            else if (this.I_OUTPUTBCRREADRESULT == 2) //扫码失败
            {
                this.AGVPortOutputBCRReadFail();
            }
            else if (this.I_OUTPUTBCRREADRESULT == 3)//扫码重复
            {
                this.AGVPortOutputBCRReadMismatch();
            }
            else
            {
                //其他case; 弹窗提醒扫码结果上报错误
            }
        }
        private void MGVPortBCRReadSuccess()
        {
            this.InputBCRReadStatus = enumIDReadState.SUCCESS;

            //从PLC读取物料ID信息.
            this.carrierId = this.GetCarrierIDFromPLC();
            LogHelper.loggerInfo(string.Format("MGV Port[{0}]口读码成功，物料ID为:[{1}]",this.HostID,this.CarrierId));
            //创建物料对象，存入carriers集合，存入数据库表
            this.LftSem.InstallMaterial(this.CarrierId, base.HostID, "", CarrierState.INSTALLED, CarrierType.CA_TRAY, this.InputBCRReadStatus.ToString(), Carrier.MaterialCreateTypeConstants.AUTO);
            //给MES发送扫码读取完成事件
            this.LftSem.SecsDriver.SendMessage("S6F11", "601", this);
        }
        private void MGVPortBCRReadFail()
        {
            string BCR_HandResultByFloor_PropVal = this.LftSem.GetUserDefinedPropertyValue("BCR_HandResultByFloor", "F", true);
            //是否通过楼层区分扫码逻辑处理
            if ("T".Equals(BCR_HandResultByFloor_PropVal.Trim()))
            {
                //如果楼层是在1楼
                if (this.Floor == 10)
                {
                    //设备报警
                    //弹窗提醒，或记录Log日志
                }
                else
                {
                    this.InputBCRReadStatus = enumIDReadState.FAILURE;
                    //创建失败的物料ID上报
                    string unkMaterialID = Util.CreateCarrierID("UNKNOWN-");
                    this.CarrierId = unkMaterialID;
                    this.LftSem.InstallMaterial(unkMaterialID, base.HostID, "", CarrierState.INSTALLED, CarrierType.CA_TRAY, this.InputBCRReadStatus.ToString(), Carrier.MaterialCreateTypeConstants.AUTO);

                    //PC自动生成指令搬送到默认Port口，上报MCS
                    this.PCAutoCreateCommand();
                }
            }
            else
            {
                //设备报警
                //弹窗提醒，或记录Log日志
            }
        }
        private void AGVPortBCRReadSuccess()
        {
            this.InputBCRReadStatus = enumIDReadState.SUCCESS;

            //从PLC读取物料ID信息.
            this.carrierId = this.GetCarrierIDFromPLC();
            if (string.IsNullOrEmpty(this.carrierId))
            {
                LogHelper.loggerInfo("在AGVPortBCRReadSuccess方法AGV模式下扫码成功时，读取物料ID为空");
                Thread.Sleep(1000);
                this.carrierId = this.GetCarrierIDFromPLC();
            }
            //判断相同位置上是否有物料，有则删除物料
            string carrierIdByLocation = Naming.GetCarrierManager().GetCarrierIdByLocation(this.HostID);
            if (!string.IsNullOrEmpty(carrierIdByLocation))
            {
                //弹窗提醒，在同一位置上已经存在物料
                //
                //
                //
                Carrier carrier = Naming.GetCarrierManager().GetCarrier(carrierIdByLocation);
                this.LftSem.CarrierStateChange(carrier, CarrierState.NONE);
                carrier.CompleteResult = Carrier.MaterialCompleteTypeConstants.RESULT_NG_CANCEL;
                Naming.GetCarrierManager().DeleteCarrier(carrierIdByLocation);
                MaterialInfoControl.materialInfoControl.UpdateDelegate();
            }
            //创建物料对象，存入carriers集合，存入数据库表
            this.LftSem.InstallMaterial(this.CarrierId, base.HostID, "", CarrierState.INSTALLED, CarrierType.CA_TRAY, this.InputBCRReadStatus.ToString(), Carrier.MaterialCreateTypeConstants.AUTO);
            if (this.lifterPortState != enumRIDState.DOWN)
            {
                //给HOST发送扫码读取完成事件
                this.LftSem.SecsDriver.SendMessage("S6F11", "601", this);
                string msg = string.Format("Port[{0}]给MCS上报扫码完成事件，扫码结果[{1}]",this.HostID, this.InputBCRReadStatus);
                LogHelper.loggerInfo(msg);
            }
        }
        private void AGVPortOutputBCRReadSuccess()
        {
            this.InputBCRReadStatus = enumIDReadState.SUCCESS;

            //从PLC读取物料ID信息.
            this.carrierId = this.GetCarrierIDFromPLC();
            if (this.lifterPortState != enumRIDState.DOWN)
            {
                //给HOST发送扫码读取完成事件
                this.LftSem.SecsDriver.SendMessage("S6F11", "601", this);
                string msg = string.Format("Port[{0}]给MCS上报出料扫码完成事件，扫码结果[{1}]", this.HostID, this.InputBCRReadStatus);
                LogHelper.loggerInfo(msg);
            }
        }
        private void AGVPortOutputBCRReadFail()
        {
            Carrier carrier = this.lftSem.GetCarrierByCarrierID(this.CarrierId);
            if (carrier != null)
            {
                carrier.OutputBCRReadMismatchFlag = true;
            }
            this.InputBCRReadStatus = enumIDReadState.FAILURE;
            //创建失败的物料ID上报
            string unkMaterialID = Util.CreateCarrierID("UNKNOWN-");
            this.CarrierId = unkMaterialID;
            this.I_BUFFERMATERIALID = unkMaterialID;
            this.LftSem.InstallMaterial(unkMaterialID, base.HostID, "", CarrierState.WAITOUT, CarrierType.CA_TRAY, this.InputBCRReadStatus.ToString(), Carrier.MaterialCreateTypeConstants.AUTO);
            if (this.lifterPortState != enumRIDState.DOWN)
            {
                //给MCS发送扫码读取完成事件
                this.LftSem.SecsDriver.SendMessage("S6F11", "601", this);
                string msg = string.Format("Port[{0}]给MCS上报扫码完成事件，扫码结果[{1}]", this.HostID, this.InputBCRReadStatus);
                LogHelper.loggerInfo(msg);
            }
            MaterialInfoControl.materialInfoControl.UpdateDelegate();
        }
        private void AGVPortOutputBCRReadMismatch()
        {
            Carrier carrier = this.lftSem.GetCarrierByCarrierID(this.OutputCarrierID);
            if (carrier != null)
            {
                carrier.OutputBCRReadMismatchFlag = true;
            }
            this.InputBCRReadStatus = enumIDReadState.DUPLICATED;
            this.CarrierId = this.I_BUFFERMATERIALID;
            this.LftSem.InstallMaterial(this.CarrierId, base.HostID, "", CarrierState.WAITOUT, CarrierType.CA_TRAY, this.InputBCRReadStatus.ToString(), Carrier.MaterialCreateTypeConstants.AUTO);

            if (this.lifterPortState != enumRIDState.DOWN)
            {
                //给MES发送扫码读取完成事件
                this.LftSem.SecsDriver.SendMessage("S6F11", "601", this);
                string msg = string.Format("Port[{0}]给MCS上报出料扫码完成事件，扫码结果[{1}]", this.HostID, this.InputBCRReadStatus);
                LogHelper.loggerInfo(msg);
            }
            MaterialInfoControl.materialInfoControl.UpdateDelegate();
        }
        private void AGVPortBCRReadFail()
        {
            this.InputBCRReadStatus = enumIDReadState.FAILURE;
            //创建失败的物料ID上报
            string unkMaterialID = Util.CreateCarrierID("UNKNOWN-");
            this.CarrierId = unkMaterialID;
            this.I_BUFFERMATERIALID = unkMaterialID;
            this.LftSem.InstallMaterial(unkMaterialID, base.HostID, "", CarrierState.INSTALLED, CarrierType.CA_TRAY, this.InputBCRReadStatus.ToString(), Carrier.MaterialCreateTypeConstants.AUTO);
            if (this.lifterPortState != enumRIDState.DOWN)
            {
                //给MES发送扫码读取完成事件
                this.LftSem.SecsDriver.SendMessage("S6F11", "601", this);
                string msg = string.Format("Port[{0}]给MCS上报扫码完成事件，扫码结果[{1}]", this.HostID, this.InputBCRReadStatus);
                LogHelper.loggerInfo(msg);
            }
        }
        private void AGVPortBCRReadDup()
        {
            //判断扫码的ID是否在物料集合种已经存在
            Carrier carrierUnsafe = Naming.GetCarrierManager().GetCarrierUnsafe(this.CarrierId);
            if (carrierUnsafe != null)
            {
                string materialLocation = this.LftSem.ConvertHostIDtoElementID(carrierUnsafe.CarrierLoc);
                this.InputBCRReadStatus = enumIDReadState.DUPLICATED;
                //弹窗提醒，物料ID重复，搬送物料中已经存在此物料
                //
                //
                //
                //判断重复的码是否在相同的port位置
                if (materialLocation.Equals(this.elementId))
                {
                    LogHelper.loggerInfo("Cst Id Duplicattion CstID:" + this.CarrierId + "Port Id:" + base.HostID);
                }
                //创建重复的物料对象，物料ID以DUP开头
                string unkMaterialID = Util.CreateCarrierID("UNKNOWNDUP-");
                this.CarrierId = unkMaterialID;
                this.I_BUFFERMATERIALID = unkMaterialID;
                this.LftSem.InstallMaterial(unkMaterialID, base.HostID, "", CarrierState.INSTALLED, CarrierType.CA_TRAY, this.InputBCRReadStatus.ToString(), Carrier.MaterialCreateTypeConstants.AUTO);

                if (this.lifterPortState != enumRIDState.DOWN)
                {
                    //给MES发送扫码读取完成事件
                    this.LftSem.SecsDriver.SendMessage("S6F11", "601", this);
                    string msg = string.Format("Port[{0}]给MCS上报扫码完成事件，扫码结果[{1}]", this.HostID, this.InputBCRReadStatus);
                    LogHelper.loggerInfo(msg);
                }
            }
            else
            {
                LogHelper.loggerInfo("设备物料没有重复");
                Console.WriteLine("设备物料没有重复");
            }
        }
        /// <summary>
        /// 当触发WaitIN时触发此事件
        /// </summary>
        private void OnWaitIn()
        {
            //判断当前port模式是否为IN模式
            if (this.PortInOutMode != enumLifterPortDirection.IN)
            {
                LogHelper.loggerInfo("在Output Port["+ this.HostID +"]上发生了 W.I 事件.");
            }
            else
            {
                string carrierFromPLC = this.GetCarrierIDFromPLC();
                Carrier carrierLocal = Naming.GetCarrierManager().GetCarrier(this.CarrierId);
                if (carrierLocal == null)
                {
                    //弹窗，写入Log日志（发生Wait in事件时，物料信息为空）
                    LogHelper.loggerInfo("发生Wait in事件时，物料信息为空");
                }
                else
                {
                    if (!carrierLocal.CarrierId.Equals(carrierFromPLC))
                    {
                        //弹窗，写入Log日志（WaitIn事件帐料不匹配）
                        LogHelper.loggerInfo("WaitIn事件帐料不匹配!");
                        //弹窗提醒
                        //
                        //
                    }
                    //将物料状态改为WAITIN(NONE -> WAITIN)
                    this.lftSem.CarrierStateChange(carrierLocal, CarrierState.WAITIN);
                    this.IsHostCommandTimeOut = false;
                    //改变Port口状态为WaitIn
                    this.WaitIn = PortWIWO.WAIT_IN;
                    //触发waitin时的当前时间
                    this.WaitInTime = DateTime.Now;
                    this.InnerPublishEvent(LifterPortEvent.LifterPortEventType.WI);
                    LogHelper.loggerInfo("WaitIn事件帐料不匹配!");
                }
            }
        }
        private void OnWaitInOff()
        {
            this.InnerPublishEvent(LifterPortEvent.LifterPortEventType.WI);
        }
        /// <summary>
        /// buffer上有实物触发信号，调用此事件
        /// 1.给buffer赋值CSTID
        /// 2.
        /// </summary>
        /// <param name="bufAddr"></param>
        private void OnBufferMaterialPresenceOn(int bufAddr)
        {
            try
            {
                //判断PORTMODE是否为OUT
                if (this.portInOutMode == enumLifterPortDirection.OUT)
                {
                    this.CarrierId = this.GetBufferCarrierID();
                    this.OutputCarrierID = this.CarrierId;
                    Console.WriteLine("OutPort口在籍ID:" + this.carrierId);
                    LogHelper.loggerInfo(string.Format("OutPort口[{0}]在籍上报，物料ID为:[{1}]",this.HostID,this.CarrierId));
                    Carrier carrier = Naming.GetCarrierManager().GetCarrier(this.CarrierId);
                    if (carrier != null)
                    {
                        carrier.SetCarrierCurrentLocation(base.HostID);
                        //上报MCS CarrierLocationChange事件
                        //this.LftSem.SecsDriver.SendMessage("S6F11", "305", carrier);
                    }
                    else
                    {
                        //弹窗提醒，或记录Log日志（出料Port，上报CarrierLocationChange事件时，获取的物料为空）
                        LogHelper.loggerInfo("出料Port，上报CarrierLocationChange事件时，获取的物料为空");
                    }
                }
                else
                {
                    this.CarrierId = this.GetBufferCarrierID();
                    /*                        this.CarrierId = "";
                                            //给buffer1cstID赋值为空
                                            this.I_BUFFERMATERIALID = "";*/
                    Carrier carrier = Naming.GetCarrierManager().GetCarrier(this.CarrierId);
                    if (carrier != null)
                    {
                        carrier.SetCarrierCurrentLocation(base.HostID);
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.loggerError("在[OnBufferMaterialPresenceOn]方法中报错", ex);
            }
            //推送buffer上是否有实物到前端页面显示
            this.InnerPublishEvent(LifterPortEvent.LifterPortEventType.CSTPRESENCE);
        }
        /// <summary>
        /// 实物从buffer上流走，buffer上没有实物触发此事件
        /// </summary>
        /// <param name="bufAddr"></param>
        private void OnBufferMaterialPresenceOff(int bufAddr)
        {
            this.InnerPublishEvent(LifterPortEvent.LifterPortEventType.CSTPRESENCE);
            //如果Port状态是Down，则上报MCS 308（carrierRemoveCompelete）事件
            if (this.LifterPortState == enumRIDState.DOWN)
            {
                Carrier carrier = this.LftSem.GetCarrierByCarrierID(this.CarrierId);
                if (carrier != null)
                {
                    carrier.CompleteResult = Carrier.MaterialCompleteTypeConstants.RESULT_NG_CANCEL;
                    this.LftSem.SecsDriver.SendMessage("S6F11", "308", carrier);
                    Naming.GetCarrierManager().DeleteCarrier(carrier.CarrierId);
                    LogHelper.loggerInfo("上报MCS carrierRemoveComplete(308)事件，并删除本地的物料信息。物料ID为:" + carrier.CarrierId);
                    MaterialInfoControl.materialInfoControl.UpdateDelegate();
                }
                else
                {
                    Console.WriteLine("Port状态为down，且Port("+ this.HostID +")在籍Off后，上报MCS carrierRemoveCompelete事件时，物料为空");
                    LogHelper.loggerInfo("Port状态为down，且Port(" + this.HostID + ")在籍Off后，上报MCS carrierRemoveCompelete事件时，物料为空");
                }
            }
            LogHelper.loggerInfo("Port[" + this.HostID + "]物料在位信号Off");
            Console.WriteLine("Port("+this.HostID+")物料在位信号Off，清空Port的物料ID");
        }
        private void OnPortHandOffTypeChange()
        {
            string xMsg = "/" + base.HostID + "/PORT TYPE/HAND OFF TYPE CHANGED, PORT TYPE: " + HandOffType.ValueToString(this.PortHandoffType);
            LogHelper.loggerInfo(xMsg);
            this.InnerPublishEvent(LifterPortEvent.LifterPortEventType.HANDOFFTYPE);
        }
        private void OnPortEventStateChange()
        {
            try
            {
                this.InnerPublishEvent(LifterPortEvent.LifterPortEventType.PORTSTATE);
            }
            catch (Exception ex)
            {
                LogHelper.loggerError("在[OnPortEventStateChange]方法中报错",ex);
            }
        }
        public enumAIMLifertPortInOutType GetAimLifertPortInOutType()
        {
            enumAIMLifertPortInOutType result;
            if (this.PortInOutMode == enumLifterPortDirection.BOTH)
            {
                result = enumAIMLifertPortInOutType.BOTH;
            }
            else
            {
                result = ((this.portInOutMode == enumLifterPortDirection.IN) ? enumAIMLifertPortInOutType.INPUT : enumAIMLifertPortInOutType.OUTPUT);
            }
            return result;
        }
        /// <summary>
        /// 等待出port
        /// </summary>
        private void OnWaitOutOn()
        {
            //判断port口模式是否为out模式
            if (this.PortInOutMode != enumLifterPortDirection.OUT)
            {
                string xMsg = "/" + base.HostID + "/W.O/Report W.O on Not OUT MODE";
                LogHelper.loggerInfo(xMsg);
            }
            Carrier carrier = Naming.GetCarrierManager().GetCarrier(this.CarrierId);
            //改变物料状态为WaitOut状态,并上报MCS
            this.LftSem.CarrierStateChange(carrier, CarrierState.WAITOUT);
            //判断Port口对接的是AGV/MGV/RGV,根据不同的对接模式进行操作
            //Port口对接AGV
            if (this.PortHandoffType == HandOffType.AGV)
            {

            }
            //Port口对接RGV
            if (this.PortHandoffType == HandOffType.RGV)
            {

            }
            //Port口对接MGV
            if (this.PortHandoffType == HandOffType.MGV)
            {

            }
            //改变页面Port口状态
            this.InnerPublishEvent(LifterPortEvent.LifterPortEventType.WO);
        }
        private void OnWaitOutOff()
        {
            try
            {
                this.InnerPublishEvent(LifterPortEvent.LifterPortEventType.WO);
                Carrier carrier = Naming.GetCarrierManager().GetCarrier(this.CarrierId);
                //上报MCS 物料remove上报
                this.LftSem.SecsDriver.SendMessage("S6F11", "301",this);
                LogHelper.loggerInfo("物料出Port口，waitOut Off,上报MCS CarrierRemove(301)事件");
                Console.WriteLine("物料出Port口，waitOut Off,上报MCS CarrierRemove(301)事件");
                carrier.CompleteResult = Carrier.MaterialCompleteTypeConstants.RESULT_OK;
                //如果指令还残留，则删除指令
                TransferWorkItem jobByCarrierID = this.lftSem.LDispatcher.GetJobByCarrierID(this.CarrierId);
                if (jobByCarrierID != null)
                {
                    this.lftSem.LDispatcher.AbortCompleteJob(jobByCarrierID.CommandID);
                    LogHelper.loggerInfo($"物料在Port[{this.HostID}]出设备，carrierRemove时，还存在残留指令[{jobByCarrierID.CommandID}]");
                }
                //删除物料信息
                Naming.GetCarrierManager().DeleteCarrier(this.CarrierId);
                LogHelper.loggerInfo("删除物料信息，物料ID为:" + this.CarrierId);
                Console.WriteLine("删除物料信息，物料ID为:" + this.CarrierId);
                MaterialInfoControl.materialInfoControl.UpdateDelegate();
                //清空Port口绑定的物料ID
                this.CarrierId = "";
                LogHelper.loggerInfo("删除Port口绑定的物料ID");
                Console.WriteLine("删除Port口绑定的物料ID");
            }
            catch (Exception ex)
            {
                LogHelper.loggerError("在OnWaitOutOff方法中", ex);
            }
        }

        /// <summary>
        /// PC自动创建Carrial指令，目的地为默认地址
        /// </summary>
        public void PCAutoCreateCommand()
        {
            string destinationPort;
            //获取指令超时的默认搬送目的地
            string hostCommandTimeOutDefaultPortID = base.GetUserDefinedPropertyValue("HOSTCOMMANDTIMEOUT_DEFAULTPORT", "", true);
            if (!string.IsNullOrEmpty(hostCommandTimeOutDefaultPortID))
            {
                destinationPort = hostCommandTimeOutDefaultPortID;
            }
            else
            {
                if (this.LftSem.HostControlState == enumHostControlState.SC_ONLINE_HOST)
                {
                    //在Online模式下指定目标Port
                    if (this.UseDestPortFlag)
                    {
                        destinationPort = this.OfflineAutoCMD_DestPort;
                    }
                    else
                    {
                        //根据Port口负载均衡分配Port口
                        destinationPort = this.GetBalanceDesPort();
                        if (string.IsNullOrEmpty(destinationPort))
                        {
                            destinationPort = this.OfflineAutoCMD_DestPort;
                        }
                    }
                }
                else
                {
                    //modify by YSL
                    destinationPort = this.OfflineAutoCMD_DestPort;
                }
            }

            //如果目的地不为空
            if (!string.IsNullOrEmpty(destinationPort))
            {
                LifterPort lifterPort = this.LftSem.GetLifterPort(destinationPort);
                if (lifterPort != null)
                {
                    //获取buffer2的CSTID绑定的搬送指令，如果指令为空，则创建命令
                    TransferWorkItem transferCommand = this.lftSem.LDispatcher.GetWorkItemByCarrierID(this.carrierId);
                    if (transferCommand == null)
                    {
                        this.LftSem.LDispatcher.AddNewTransferQueue(this.carrierId, destinationPort, this.HostID);
                    }
                }
                else
                {
                    LogHelper.loggerInfo(string.Format("在PCAutoCreateCommand方法中,通过目的地ID[{0}]获取的目的地信息为空",destinationPort));
                }
            }
            else
            {
                LogHelper.loggerInfo("在PCAutoCreateCommand方法中，在创建指令时，获取的目的地ID为空");
            }
        }
        /// <summary>
        /// Add By yangshl 2023/9/11
        /// 根据目的地Port口，将指令分组，选出指令数量最少的一组，返回该组指令的目的地
        /// </summary>
        /// <returns>目的地</returns>
        private string GetBalanceDesPort()
        {
            string result = "";
            List<TransferWorkItem> transferLists = this.LftSem.LDispatcher.workList;
            if (transferLists.Count > 0)
            {
                int tempNum = 1000;
                IGrouping<string, TransferWorkItem> transferCommand = null;
                //根据目标口分组
                lock (this.LftSem.LDispatcher.workList_monitor)
                {
                    var transferGroups = transferLists.GroupBy(key => key.Dest);
                    //选出指令数量最少的一组，返回该组指令的目的地
                    foreach (var item in transferGroups)
                    {
                        if (item.Count() <= tempNum)
                        {
                            tempNum = item.Count();
                            transferCommand = item;
                        }
                    }
                }
                result = transferCommand.Key;
                return result;
            }
            else
            {
                return result;
            }
        }
        /// <summary>
        /// 获取BUFFER的CSTID
        /// </summary>
        /// <param name="bufferIndex"></param>
        /// <returns></returns>
        public string GetBufferCarrierID()
        {
            string text = "";
            string result;
            text = this.I_BUFFERMATERIALID;
            if (!string.IsNullOrEmpty(text))
            {
                result = text;
            }
            else
            {
                result = this.CarrierId;
            }
            return result;
        }
        public string GetCarrierIDFromPLC()
        {
            string bufferMaterialID = this.I_BUFFERMATERIALID;

            return bufferMaterialID;
        }
        public void SetCSTIDtoPLCBuffer(int BufferIndex, string CSTID)
        {
            CSTID = CSTID.ToUpper();
            this.I_BUFFERMATERIALID = CSTID;
        }
        public void OnNextLocationValueChange()
        {
            this.InnerPublishEvent(LifterPortEvent.LifterPortEventType.NEXTLOCATION);
        }
        public void InnerPublishEvent(LifterPortEvent.LifterPortEventType type)
        {
            base.PublishEvent(LifterPortEvent.FormSubject(this.elementId), new LifterPortEvent(this.ownerId, EquipmentType.ValueToString(EquipmentType.LIFTER), base.ID, type));
        }
        private void InnerPublishEvent(LifterPortDirectionEvent.enumLifterPortDirectionEventType type)
        {
            base.PublishEvent(LifterPortDirectionEvent.FormSubject(this.elementId), new LifterPortDirectionEvent(this.ownerId, EquipmentType.ValueToString(EquipmentType.LIFTER), base.ID, type));
            // base.PublishEvent(PortStatusEvent.FormSubject("*"), new PortStatusEvent(this.elementId, EquipmentType.ValueToString(EquipmentType.LIFTER), this.UseChange));
        }
        public enumAIMLifertPortInOutType GetLifterPortInoutType()
        {
            enumAIMLifertPortInOutType result;
            if (this.PortInOutMode == enumLifterPortDirection.IN)
            {
                result = enumAIMLifertPortInOutType.INPUT;
            }
            else if (this.PortInOutMode == enumLifterPortDirection.OUT)
            {
                result = enumAIMLifertPortInOutType.OUTPUT;
            }
            else if (this.PortInOutMode == enumLifterPortDirection.BOTH)
            {
                result = enumAIMLifertPortInOutType.BOTH;
            }
            else
            {
                result = enumAIMLifertPortInOutType.UNKNOWN;
            }
            return result;
        }
        public void DoPortInOutModeChange(bool value)
        {
            if (value)
            {
                this.O_OUTPUTMODEREQ = true;
            }
            else
            {
                this.O_INPUTMODEREQ = true;
            }
        }
        private void CimCommandAndAckSetReset(LifterPort.enumCIMPortSetResetCase cimCase, bool value)
        {
            switch (cimCase)
            {
                case LifterPort.enumCIMPortSetResetCase.FAULT_RESET:
                    if (value)
                    {
                        this.O_FAULTRESET = true;
                    }
                    else
                    {
                        if (this.isFAULTRESET)
                        {
                            this.O_FAULTRESET = false;
                        }
                    }
                    break;
                case LifterPort.enumCIMPortSetResetCase.RUN_REQ:
                    if (value)
                    {
                        this.O_RUNREQ = true;
                    }
                    else
                    {
                        if (this.isRunReqeust)
                        {
                            this.O_RUNREQ = false;
                        }
                    }
                    break;
                case LifterPort.enumCIMPortSetResetCase.DOWN_REQ:
                    if (value)
                    {
                        this.O_DOWNREQ = true;
                    }
                    else
                    {
                        if (this.isDownReqeust)
                        {
                            this.O_DOWNREQ = false;
                        }
                    }
                    break;
                case LifterPort.enumCIMPortSetResetCase.INPUT_MODE_REQ:
                    if (value)
                    {
                        this.O_INPUTMODEREQ = true;
                    }
                    else
                    {
                        if (this.isINPUTMODEREQ)
                        {
                            this.O_INPUTMODEREQ = false;
                        }
                    }
                    break;
                case LifterPort.enumCIMPortSetResetCase.OUTPUT_MODE_REQ:
                    if (value)
                    {
                        this.O_OUTPUTMODEREQ = true;
                    }
                    else
                    {
                        if (this.isOUTPUTMODEREQ)
                        {
                            this.O_OUTPUTMODEREQ = false;
                        }
                    }
                    break;
                case LifterPort.enumCIMPortSetResetCase.BI_MODE_REQ:
                    if (value)
                    {
                        this.O_BIDIRECTIONMODEREQ = true;
                    }
                    else
                    {
                        if (this.isBIDIRECTIONMODEREQ)
                        {
                            this.O_BIDIRECTIONMODEREQ = false;
                        }
                    }
                    break;
                case LifterPort.enumCIMPortSetResetCase.INPUT_PORT_BCR_SET:
                    if (value)
                    {
                        this.O_INPUTPORTBCRSET = true;
                    }
                    else
                    {
                        if (this.isINPUTPORTBCRSET)
                        {
                            this.O_INPUTPORTBCRSET = false;
                            this.IO_CSTIDBUFFER1 = "";
                        }
                    }
                    break;
                case LifterPort.enumCIMPortSetResetCase.INPUT_RF_READ_DONE_ACK:
                    this.O_INPUTRFREADDONEACK = value;
                    break;
                case LifterPort.enumCIMPortSetResetCase.OUPUT_RF_READ_DONE_ACK:
                    this.O_OUTPUTRFREADDONEACK = value;
                    break;
            }
        }
        private void CimAllCmdReset()
        {
            this.CimCommandAndAckSetReset(LifterPort.enumCIMPortSetResetCase.BI_MODE_REQ, false);
            this.CimCommandAndAckSetReset(LifterPort.enumCIMPortSetResetCase.DOWN_REQ, false);
            this.CimCommandAndAckSetReset(LifterPort.enumCIMPortSetResetCase.FAULT_RESET, false);
            this.CimCommandAndAckSetReset(LifterPort.enumCIMPortSetResetCase.INPUT_MODE_REQ, false);
            this.CimCommandAndAckSetReset(LifterPort.enumCIMPortSetResetCase.INPUT_PORT_BCR_SET, false);
            this.CimCommandAndAckSetReset(LifterPort.enumCIMPortSetResetCase.OUTPUT_MODE_REQ, false);
            this.CimCommandAndAckSetReset(LifterPort.enumCIMPortSetResetCase.RUN_REQ, false);
        }
        public void ReserveUserInputCSTID(string reservCSTID)
        {
            this.isIUsernputCSTIDReserved = true;
            this.strReservedCSTID = reservCSTID.ToUpper().Trim();
        }
        public void ResetUserInputCSTID()
        {
            this.isIUsernputCSTIDReserved = false;
            this.strReservedCSTID = "";
        }

        #region add by yangshl Port操作方法

        #endregion
    }
}
